﻿using CKS.Core.Framework;
using FreeSql;
using Infrastructure;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZR.Model.Models.ProductionControl;
using ZR.Service.IService.ProductionControl;

namespace CKS.PLC.Action.Subscription.OP080
{
    public abstract class OP80ActionBase : SaveProcessingResults
    {
        
        protected OP80ActionBase(DecodeValue _value) : base(_value)
        {
           
        }

       public int BrazingCellCount = 243;//钎焊料架存储总数
        public int PalletizerCellCount = 216;//码垛机料架单元格总数
        /// <summary>
        /// 更新工装位置，更新料架信息
        /// </summary>
        /// <param name="locationId"></param>
        public void SaveFixtureInfos(int locationId )
        {
            int RackNum = Value.GetLinkData(1).ToInt(); // 钎焊料架编号
            var cells = BuildShelf(RackNum); //料架格子信息



            var arr1 = Value.GetLinkData(2).Adapt<List<int>>();//状态
            var arr2 = Value.GetLinkData(3).Adapt<List<int>>(); //夹具编号
            for (int i = 0; i < arr1.Count; i++)
            {
                var fixtureinfo = new CksFixtureinfo();
                var cell = cells[i];
                cell.LocationId = locationId;
                cell.FixtureId = arr2[i];
                cell.Status = arr1[i];
                cell.CellId = i + 1;
                //更新料架格子信息，如果当前夹具信息，已存在料架内位置，先更新料架位置的储物信息
                if(cell.FixtureId>0)
                {
                    ResetShelfCell(cell.FixtureId);

                }
                cell.UpdateTime = DateTime.Now;
              
                int rowcount = fsql.Update<CksShelfForFixture>().SetSource(cell).ExecuteAffrows();
              

                //更新当前夹具信息
                fixtureinfo.CellId = cell.CellId;
                fixtureinfo.Status = arr1[i];
                fixtureinfo.ShelfId = RackNum;
                fixtureinfo.LocationId = locationId;
                fixtureinfo.FixtureId = arr2[i];

                if (fixtureinfo.FixtureId == 0)
                {
                    //说明当前位置的夹具不存在 : 立即更新在此位置的夹具，重置料架位置
                    conn.Update<CksFixtureinfo>()
                        .Set(a=>a.CellId,0)
                        .Set(a=>a.ShelfId,0)
                        .Where(a=>a.ShelfId == fixtureinfo.ShelfId && a.CellId == fixtureinfo.CellId )
                        .ExecuteAffrows();
                    continue; 
                }

                //存在更新，否则插入
                var model = conn.Select<CksFixtureinfo>().Where(a => a.FixtureId == fixtureinfo.FixtureId).First();
                if (model == null)
                {
                    fixtureinfo.MaxUsageCount = 200;
                    conn.Insert<CksFixtureinfo>(fixtureinfo).ExecuteAffrows();
                   
                }
                else
                {
                    fixtureinfo.Id = model.Id;
                    fixtureinfo.UpdateTime = DateTime.Now;
                    conn.Update<CksFixtureinfo>().SetSource(fixtureinfo)
                        .UpdateColumns(a => new { a.Status, a.LocationId, a.FixtureId,a.UpdateTime ,a.ShelfId,a.CellId })
                        .ExecuteAffrows();
                }
            }

            //更新当前使用的料架编号
            var regionid =Value.Position.ActionId == 101 ? 1 : 2;
            conn.Update<DcOp80CurrentShelf>().Set(a=>a.ShelfId,RackNum)
                .Where(a=>a.Id == regionid).ExecuteAffrows();
        
        }

        public void ResetShelfCell(int FixtureId )
        {
            
            conn.Update<CksShelfForFixture>()
                .Set(a => a.FixtureId, 0)
                .Set(a => a.Status, 0).Where(a => a.FixtureId == FixtureId)
                .ExecuteAffrows();
        }

        private static readonly object _lock = new object();
        /// <summary>
        /// 查询料架信息，不存在则生成此料架
        /// </summary>
        /// <param name="rackNum"></param>
        /// <exception cref="NotImplementedException"></exception>
        private List<CksShelfForFixture> BuildShelf(int ShelfId)
        {
            lock (_lock)
            {
                
                var cells = conn.Select<CksShelfForFixture>().Where(a => a.ShelfId == ShelfId).OrderBy(a => a.CellId).ToList();
                if (cells.Count == 0)
                {
                    for (int i = 1; i <= BrazingCellCount; i++)
                    {
                        CksShelfForFixture slot = new CksShelfForFixture();
                        slot.CellId = i;
                        slot.ShelfId = ShelfId;


                        cells.Add(slot);
                    }
                    conn.Insert(cells).ExecuteAffrows();
                    cells = conn.Select<CksShelfForFixture>().Where(a => a.ShelfId == ShelfId).OrderBy(a => a.CellId).ToList();
                }
                return cells;
            }
            

        }

        /// <summary>
        /// 查询码垛机料架表
        /// </summary>
        /// <param name="ShelfId"></param>
        /// <returns></returns>
        public List<CksShelfPalletizer> BuildShelfPalletizer(int ShelfId)
        {
            lock (_lock)
            {

                var cells = conn.Select<CksShelfPalletizer>().Where(a => a.ShelfId == ShelfId).OrderBy(a => a.CellId).ToList();
                if (cells.Count == 0)
                {
                    for (int i = 1; i <= PalletizerCellCount; i++)
                    {
                        CksShelfPalletizer slot = new CksShelfPalletizer();
                        slot.CellId = i;
                        slot.ShelfId = ShelfId;
                        cells.Add(slot);
                    }
                    conn.Insert(cells).ExecuteAffrows();
                    cells = conn.Select<CksShelfPalletizer>().Where(a => a.ShelfId == ShelfId).OrderBy(a => a.CellId).ToList();
                }
                return cells;
            }


        }



        /// <summary>
        /// 查询料架信息并上传
        /// </summary>
        /// <exception cref="Exception"></exception>
        public void QueryFixtureToPLC(int replayDB, int replayAction, CksPlcDataPosition replayPos, int shelfId)
        {
            var fixtureinfos = conn.Select<CksShelfForFixture>()
                                .Where(a => a.ShelfId == shelfId).OrderBy(a => a.CellId).ToList();
            if (fixtureinfos.Count == BrazingCellCount)
            {
                var shelfPos = Value.GetPosition(replayDB, replayAction, 1);
                var statusPos = Value.GetPosition(replayDB, replayAction, 2);
                var codePos = Value.GetPosition(replayDB, replayAction, 3);
                var intOffset = 0;
                for (var i = 0; i < fixtureinfos.Count; i++)
                {
                    var ft = fixtureinfos[i];
                    var startByteAdrOfStatus = ((int)statusPos.BytePosition) + intOffset;
                    var startByteAdrOfCode = ((int)codePos.BytePosition) + intOffset;
                    WriteInt16(replayDB, startByteAdrOfStatus, (short)ft.Status);
                    WriteInt16(replayDB, startByteAdrOfCode, (short)ft.FixtureId);
                    //int 数组偏移量2
                    intOffset += 2;
                }
                //写入料架号
                AckWriteInt16(shelfPos, (short)shelfId);
                //写入完成写入回复信号
                AckWriteInt16(replayPos, 1);

            }
            else
            {
                string message = $"查询料架号{shelfId}数量大于216";
                logger.LogError(message);
                throw new Exception(message);
            }
        }
    }
}
